import 'dart:core';
import 'dart:math';
import 'dart:typed_data';

import 'package:flutter_common_utils/flutter_common_utils.dart';

import 'crc_utils.dart';

Uint8List byteArrayOf(List<int> data) {
  return Uint8List.fromList(data);
}

extension CUHexUtilsByteArrayExtensions on List<int> {
  Uint8List toByteArray() => Uint8List.fromList(this);

  bool contentEquals(List<int> other) {
    if (length != other.length) return false;
    for (int i = 0; i < length; i++) {
      if (this[i] != other[i]) return false;
    }
    return true;
  }

  //比较是否以这个结尾
  bool endsWith(List<int> end) {
    // 检查输入的list长度是否足够
    if (length < end.length) return false;
    // 获取list的最后sequence.length个元素
    final suffix = sublist(length - end.length);
    // 比较后缀和给定序列是否相等
    return suffix.contentEquals(end);
  }

  //比较是否以这个开始
  bool startsWith(List<int> end) {
    // 检查输入的list长度是否足够
    if (length < end.length) return false;
    // 获取list的最后sequence.length个元素
    final suffix = sublist(0, end.length);
    // 比较后缀和给定序列是否相等
    return suffix.contentEquals(end);
  }
}

extension CUUint8ListExtensions on Uint8List {
  bool contentEquals(Uint8List other) {
    if (length != other.length) return false;
    for (int i = 0; i < length; i++) {
      if (this[i] != other[i]) return false;
    }
    return true;
  }
}

extension CUByteArrayIterableExtensions on Iterable<int> {
  Uint8List toByteArray() => Uint8List.fromList(toList());
}

extension CUHexUtilsExtensions on List<int> {
  /// crc8
  int get CRC8 => CrcUtils.CRC8(this, 0, this.length);

  int get CRC8_DARC => CrcUtils.CRC8_DARC(this, 0, this.length);

  int get CRC8_ITU => CrcUtils.CRC8_ITU(this, 0, this.length);

  int get CRC8_MAXIM => CrcUtils.CRC8_MAXIM(this, 0, this.length);

  int get CRC8_ROHC => CrcUtils.CRC8_ROHC(this, 0, this.length);

  /// crc16
  int get CRC16_CCITT_FALSE => CrcUtils.CRC16_CCITT_FALSE(this, 0);

  int get CRC16_CCITT => CrcUtils.CRC16_CCITT(this, 0, this.length);

  int get CRC16_DECT_R => CrcUtils.CRC16_DECT_R(this, 0, this.length);

  int get CRC16_DECT_X => CrcUtils.CRC16_DECT_X(this, 0, this.length);

  int get CRC16_DNP => CrcUtils.CRC16_DNP(this, 0, this.length);

  int get CRC16_GENIBUS => CrcUtils.CRC16_GENIBUS(this, 0, this.length);

  int get CRC16_IBM => CrcUtils.CRC16_IBM(this, 0, this.length);

  int get CRC16_MAXIM => CrcUtils.CRC16_MAXIM(this, 0, this.length);

  int get CRC16_MODBUS => CrcUtils.CRC16_MODBUS(this, 0, this.length);

  int get CRC16_USB => CrcUtils.CRC16_USB(this, 0, this.length);

  int get CRC16_X25 => CrcUtils.CRC16_X25(this, 0, this.length);

  int get CRC16_XMODEM => CrcUtils.CRC16_XMODEM(this, 0, this.length);

  /// crc32
  int get CRC32 => CrcUtils.CRC32(this, 0, this.length);

  int get CRC32_B => CrcUtils.CRC32_B(this, 0, this.length);

  int get CRC32_C => CrcUtils.CRC32_C(this, 0, this.length);

  int get CRC32_D => CrcUtils.CRC32_D(this, 0, this.length);

  int get CRC32_POSIX => CrcUtils.CRC32_POSIX(this, 0, this.length);

  int get CRC32_MPEG_2 => CrcUtils.CRC32_MPEG_2(this, 0, this.length);

  /// ByteArray -> 16进制字符串
  String get toHexStr => HexUtils.bytesToHexString(this).toUpperCase();

  /// ByteArray -> 16进制字符串  空格拼接
  String get toHexStrSpace => HexUtils.bytesToHexString(this, " ").toUpperCase();

  /// ByteArray -> Int32
  ByteData get byteToByteData => HexUtils.byteToByteData(this);

  /// ByteArray -> Int64
  int get byteToLong => HexUtils.byteToLong(this, reversed: true);

  int get byteToLongLE => HexUtils.byteToLong(this, reversed: false);

  /// ByteArray -> Int32
  int get byteToInt => HexUtils.byteToInt(this, reversed: true);

  int get byteToIntLE => HexUtils.byteToInt(this, reversed: false);

  /// ByteArray -> Uint
  int get byteToUInt => HexUtils.byteToUInt(this, reversed: true);

  int get byteToUIntLE => HexUtils.byteToUInt(this, reversed: false);

  /// ByteArray -> Int16
  int get byteToInt16 => HexUtils.byteToInt16(this, reversed: true);

  int get byteToInt16LE => HexUtils.byteToInt16(this, reversed: false);

  /// ByteArray -> UInt16
  int get byteToUInt16 => HexUtils.byteToUInt16(this, reversed: true);

  int get byteToUInt16LE => HexUtils.byteToUInt16(this, reversed: false);

  /// ByteArray -> Float
  double get byteToFloat => byteToInt.toBitFloat;

  double get byteToFloatLE => byteToIntLE.toBitFloat;

  /// ByteArray -> Double
  double get byteToDouble => byteToLong.toBitDouble;

  double get byteToDoubleLE => byteToLongLE.toBitDouble;

  /// ByteArray -> ASCII字符串
  String get byteToASCIIStr => HexUtils.byteToASCIIStr(this, reversed: false, isSub00: false, isRemoveControl: false);

  /// 删除00和后续
  String get byteToASCIIStrSub00 => HexUtils.byteToASCIIStr(this, reversed: false, isSub00: true, isRemoveControl: false);

  /// 删除控制字符和 00和后续
  String get byteToASCIIStrDelCtrlOr00 => HexUtils.byteToASCIIStr(this, reversed: false, isSub00: true, isRemoveControl: true);

  /// 移除控制字符
  String get byteToASCIIStrDelCtrl => HexUtils.byteToASCIIStr(this, reversed: false, isSub00: false, isRemoveControl: true);
}

extension CUHexUtilsStringExtensions on String {
  /// 字符串转换成字节数组
  Uint8List get hexToBytes => HexUtils.hexStr2Bytes(this);
}

extension CUHexUtilsIntExtensions on int {
  /// 将int转化成byte[]
  Uint8List toByteArray({int size = -1, bool isReversed = true}) => HexUtils.intToBytes(this, size: size, isReversed: isReversed);

  /// 0xffff 为4个字节和2个字节的分界线
  Uint8List toByteArray2Or4([bool isReversed = true]) => HexUtils.intToBytes2Or4(this, isReversed: isReversed);

  Uint8List toByteArray2([bool isReversed = true]) => HexUtils.intToBytes(this, size: 2, isReversed: isReversed);

  Uint8List toByteArray4([bool isReversed = true]) => HexUtils.intToBytes(this, size: 4, isReversed: isReversed);

  Uint8List toByteArray8([bool isReversed = true]) => HexUtils.intToBytes(this, size: 8, isReversed: isReversed);

  Uint8List toByteArray4Or8([bool isReversed = true]) => HexUtils.longToBytes4Or8(toInt(), isReversed: isReversed);

  /// Int -> 16进制字符串
  String get toHexStr => toByteArray2Or4(false).toHexStr;

  String get toHexStrSpace => toByteArray2Or4(false).toHexStrSpace;
}

extension CUHexUtilsDoubleExtensions on double {
  /// Int转换成Float（遵循IEEE 754标准）
  int get toBitInt => HexUtils.floatToIntBits(this);

  /// Double转换成Long（遵循IEEE 754标准）
  int get toBitLong => HexUtils.doubleToIntBits(this);
}

extension CUHexUtilsLongExtensions on int {
  /// 将long转化成byte[]
  Uint8List toByteArray4Or8([bool isReversed = true]) => HexUtils.longToBytes4Or8(this, isReversed: isReversed);

  /// Long -> 16进制字符串
  String get toHexStr4Or8 => toByteArray4Or8(false).toHexStr;

  /// Int转换成Float（遵循IEEE 754标准）
  double get toBitFloat => HexUtils.intBitsToFloat(this);

  /// Long转换成Double（遵循IEEE 754标准）
  double get toBitDouble => HexUtils.intBitsToDouble(this);
}

class HexUtils {
  HexUtils._();

  static int floatToIntBits(double value) {
    // 创建4字节缓冲区
    var buffer = Uint8List(4).buffer;
    ByteData data = ByteData.view(buffer);

    // 以IEEE 754标准将浮点数写入缓冲区
    data.setFloat32(0, value, Endian.big);

    // 读取缓冲区中的32位整数（大端序）
    return data.getInt32(0, Endian.big);
  }

  static double intBitsToFloat(int bits) {
    // 创建一个4字节的缓冲区
    var buffer = Uint8List(4).buffer;
    ByteData data = ByteData.view(buffer);
    // 将整数按大端序写入缓冲区
    data.setInt32(0, bits, Endian.big);
    // 从缓冲区中读取一个32位浮点数（按大端序）
    return data.getFloat32(0, Endian.big);
  }

  static int doubleToIntBits(double value) {
    // 创建8字节缓冲区
    var buffer = Uint8List(8).buffer;
    ByteData data = ByteData.view(buffer);

    // 以IEEE 754标准将浮点数写入缓冲区
    data.setFloat64(0, value, Endian.big);

    // 读取缓冲区中的64位整数（大端序）
    return data.getInt64(0, Endian.big);
  }

  static double intBitsToDouble(int bits) {
    // 创建一个8字节的缓冲区
    var buffer = Uint8List(8).buffer;
    ByteData data = ByteData.view(buffer);
    // 将整数按大端序写入缓冲区
    data.setInt64(0, bits, Endian.big);
    // 从缓冲区中读取一个32位浮点数（按大端序）
    return data.getFloat64(0, Endian.big);
  }

  /// 十六进制String转换成Byte[]
  static Uint8List hexStr2Bytes(String? str) {
    if (str == null || str.isEmpty) {
      return Uint8List(0);
    }
    // 替换空格
    str = str.replaceAll(" ", "");
    final byteArray = Uint8List(str.length ~/ 2);
    for (int i = 0; i < byteArray.length; i++) {
      final subStr = str.substring(2 * i, 2 * i + 2);
      byteArray[i] = int.parse(subStr, radix: 16).toUnsigned(8);
    }
    return byteArray;
  }

  /// 将字节数组转换为16进制字符串
  static String bytesToHexString(List<int>? src, [String? joint]) {
    if (src == null || src.isEmpty) {
      return "";
    }
    final b = StringBuffer();
    for (final element in src) {
      var hex = element.toRadixString(16).padLeft(2, '0');
      b.write(hex);
      if (joint != null) {
        b.write(joint);
      }
    }
    return b.toString();
  }

  /// 将int转化成byte[]
  static Uint8List intToBytes(int res, {int size = -1, bool isReversed = true}) {
    if (size <= 0) {
      if (res.toUnsigned(64) > 0xFFFFFFFFFFFFFF || res.toUnsigned(64) < 0) {
        size = 8;
      } else if (res.toUnsigned(64) > 0xFFFFFFFFFFFF) {
        size = 7;
      } else if (res.toUnsigned(64) > 0xFFFFFFFFFF) {
        size = 6;
      } else if (res.toUnsigned(64) > 0xFFFFFFFF) {
        size = 5;
      } else if (res.toUnsigned(32) > 0xFFFFFF) {
        size = 4;
      } else if (res.toUnsigned(32) > 0xFFFF) {
        size = 3;
      } else if (res.toUnsigned(32) > 0xFF) {
        size = 2;
      } else {
        size = 1;
      }
    }
    final targets = Uint8List(size);
    if (size >= 1) {
      targets[0] = (res & 0xff).toUnsigned(8); // 最低位
    }
    if (size >= 2) {
      targets[1] = ((res >> 8) & 0xff).toUnsigned(8); // 次低位
    }
    if (size >= 3) {
      targets[2] = ((res >> 16) & 0xff).toUnsigned(8); // 次高位
    }
    if (size >= 4) {
      targets[3] = ((res >>> 24) & 0xff).toUnsigned(8); // 最高位,无符号右移。
    }
    if (size >= 5) {
      targets[4] = ((res >>> 32) & 0xff).toUnsigned(8); // 最高位,无符号右移。
    }
    if (size >= 6) {
      targets[5] = ((res >>> 40) & 0xff).toUnsigned(8); // 最高位,无符号右移。
    }
    if (size >= 7) {
      targets[6] = ((res >>> 48) & 0xff).toUnsigned(8); // 最高位,无符号右移。
    }
    if (size >= 8) {
      targets[7] = ((res >>> 56) & 0xff).toUnsigned(8); // 最高位,无符号右移。
    }
    if (!isReversed) {
      targets.setAll(0, targets.reversed.toList());
    }
    return targets;
  }

  /// int 转 ByteArray  4字节和2字节
  static Uint8List intToBytes2Or4(int res, {bool isReversed = true}) {
    final targets = Uint8List(res.toUnsigned(32) > 0xFFFF ? 4 : 2);
    targets[0] = (res & 0xff).toUnsigned(8); // 最低位
    targets[1] = ((res >> 8) & 0xff).toUnsigned(8); // 次低位
    if (targets.length > 2) {
      targets[2] = ((res >> 16) & 0xff).toUnsigned(8); // 次高位
      targets[3] = ((res >>> 24) & 0xff).toUnsigned(8); // 最高位,无符号右移。
    }
    if (!isReversed) {
      targets.setAll(0, targets.reversed.toList());
    }
    return targets;
  }

  /// long 转 ByteArray  8字节和4字节
  static Uint8List longToBytes4Or8(int res, {bool isReversed = true}) {
    final targets = Uint8List(res.toUnsigned(64) > 0xFFFFFFFF || res.toUnsigned(64) < 0 ? 8 : 4);
    targets[0] = (res & 0xff).toUnsigned(8); // 最低位
    targets[1] = ((res >> 8) & 0xff).toUnsigned(8); // 次低位
    targets[2] = ((res >> 16) & 0xff).toUnsigned(8); // 次高位
    targets[3] = ((res >> 24) & 0xff).toUnsigned(8); // 最高位
    if (targets.length > 4) {
      targets[4] = ((res >> 32) & 0xff).toUnsigned(8); // 次高位
      targets[5] = ((res >> 40) & 0xff).toUnsigned(8); // 最高位
      targets[6] = ((res >> 48) & 0xff).toUnsigned(8); // 最高位
      targets[7] = ((res >>> 56) & 0xff).toUnsigned(8); // 最高位
    }
    if (!isReversed) {
      targets.setAll(0, targets.reversed.toList());
    }
    return targets;
  }

  // byte[] 转 ByteData, size为-1时，使用res.length, 长度不够时，前面填充0
  static ByteData byteToByteData(List<int> res, {int size = -1}) {
    // 确定目标长度
    final targetLength = size == -1 ? res.length : size;
    if (targetLength < 0) {
      throw ArgumentError('Size cannot be negative except for -1');
    }
    // 处理数据
    Uint8List bytes;
    if (targetLength > res.length) {
      // 目标长度 > 列表长度：前面填充0
      bytes = Uint8List(targetLength)..setRange(targetLength - res.length, targetLength, res);
    } else {
      // 目标长度 <= 列表长度：截取前 targetLength 个元素
      bytes = Uint8List.fromList(res.sublist(0, targetLength));
    }
    // 转换为 ByteData
    return ByteData.view(bytes.buffer);
  }

  /// 将byte[]转化成int
  static int byteToInt(List<int> res, {bool reversed = true}) {
    //这里如果使用ByteData实现，reversed就是相反意思
    res = !reversed ? res.reversed.toList() : res;
    //如果使用ByteData 的大小端，可能对res 长度不是4的数据转换错误
    return byteToByteData(res, size: 4).getInt32(0, Endian.big);
  }

  /// 将byte[]转化成int16
  static int byteToInt16(List<int> res, {bool reversed = true}) {
    //这里如果使用ByteData实现，reversed就是相反意思
    res = !reversed ? res.reversed.toList() : res;
    //如果使用ByteData 的大小端，可能对res 长度不是4的数据转换错误
    return byteToByteData(res, size: 2).getInt16(0, Endian.big);
  }

  /// 将byte[]转化成int16
  static int byteToUInt16(List<int> res, {bool reversed = true}) {
    //这里如果使用ByteData实现，reversed就是相反意思
    res = !reversed ? res.reversed.toList() : res;
    //如果使用ByteData 的大小端，可能对res 长度不是4的数据转换错误
    return byteToByteData(res, size: 2).getUint16(0, Endian.big);
  }

  /// 将byte[]转化成uint
  static int byteToUInt(List<int> res, {bool reversed = true}) {
    //这里如果使用ByteData实现，reversed就是相反意思
    res = !reversed ? res.reversed.toList() : res;
    //如果使用ByteData 的大小端，可能对res 长度不是4的数据转换错误
    return byteToByteData(res, size: 4).getUint32(0, Endian.big);
  }

  /// 将byte[]转化成int64  就是long
  static int byteToLong(List<int> res, {bool reversed = true}) {
    //这里如果使用ByteData实现，reversed就是相反意思
    res = !reversed ? res.reversed.toList() : res;
    //如果使用ByteData 的大小端，可能对res 长度不是4的数据转换错误
    return byteToByteData(res, size: 8).getInt64(0, Endian.big);
  }

  /// 将byte[]转化成ASCII字符串
  static String byteToASCIIStr(List<int> res, {bool reversed = true, bool isSub00 = false, bool isRemoveControl = false}) {
    res = reversed ? Uint8List.fromList(res.reversed.toList()) : res;
    final result = StringBuffer();
    for (final it in res) {
      if (isSub00 && it == 0) break;
      if (isRemoveControl && (it < 32 || it > 126)) continue;
      result.write(String.fromCharCode(it));
    }
    return result.toString();
  }
}
